#include "CollectPart.h"
#include "Character/monster/Monster.h"
#include "Common/TableData/ConstantConstantCfg.h"
#include "Common/TableDataEx/DeputyCfg.h"
#include "Common/TableData/MonsterMonsterCfg.h"
#include "Character/MovePart.h"
#include "DeputyPart.h"
#include "MissionPart.h"
#include "Character/object/ObjectMgr.h"
#include "Character/drop/DropMgr.h"
#include "Character/Player.h"

CollectPart::CollectPart()
{
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_COLLECT_COLLECT_OPERATE,	&CollectPart::Collect));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_COLLECT_QTE,				&CollectPart::Qte));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_COLLECT_SPECIAL,			&CollectPart::CollectSpecial));
	mCollectSpeed = 0;
}

CollectPart::~CollectPart()
{
}

bool CollectPart::Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB /*= nullptr*/)
{
	Part::Init(pMaster, partType);
	return true;
}

bool CollectPart::UnInit()
{
	g_GetEvent()->UnSubscribeAll(this);
	g_GetTimerAxis()->KillAllTimer(this);
	g_GetTimerAxis()->KillAllFixTimer(this);
	m_curState.Clear();
	return true;
}

bool CollectPart::OnMsgHandle(uint32_t cmd, const char* data, uint32_t len)
{
	mapMsgFunc::iterator iter = m_mapMsgfunc.find(cmd);
	if (iter == m_mapMsgfunc.end())
		LogErrFmtPrint("msg dont exit in CollectPart, cmd:%d", cmd);
	else
		(this->*m_mapMsgfunc[cmd])(data, len);

	return true;
}

void CollectPart::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	switch (nEventID)
	{
	case EVENT_UNDER_ATTACK:
	case EVENT_ATTACK_SOMEBODY:
	case EVENT_START_MOVE:		//采集中断处理
	{
		if (ECollectState_Begin == m_curState.byState)
		{
			g_GetTimerAxis()->KillTimer(0, this);
			CollectNotify notify;
			notify.set_collect_type(m_curState.byType);
			notify.set_state(ECollectState_Break);
			notify.set_collect_cid(m_curState.cid);
			m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_NOTIFY_COLLECT, &notify);
			m_curState.Clear();
			BroadcastCollectAction();
			NotifyError(RET_DEPUTY_COLLECT_BREAK);
			UnSubEvent();
		}
	}
	break;
	case EVENT_COLLECT_SUCCESS:	//当前采集物被其他角色抢走时的处理
	{
		if (ECollectState_Begin == m_curState.byState)
		{
			if ((uint32_t)nLen >= sizeof(CollectSuccessEvent))
			{
				CollectSuccessEvent *pEvent = (CollectSuccessEvent*)pContext;
				if (pEvent && pEvent->cid > 0 && pEvent->cid == m_curState.cid && nSrcID != m_pMaster->GetCid())
				{
					g_GetTimerAxis()->KillTimer(0, this);
					CollectNotify notify;
					notify.set_collect_type(m_curState.byType);
					notify.set_state(ECollectState_Break);
					notify.set_collect_cid(m_curState.cid);
					m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_NOTIFY_COLLECT, &notify);
					m_curState.Clear();
					BroadcastCollectAction();
					NotifyError(RET_DEPUTY_COLLECT_BY_OTHER);
					UnSubEvent();
				}
			}
		}
	}
	break;
	case EVENT_LEAVE_SCENE:
	{
		if (ECollectState_Begin == m_curState.byState)
		{
			if ((uint32_t)nLen >= sizeof(LeaveSceneEvent))
			{
				LeaveSceneEvent *pEvent = (LeaveSceneEvent*)pContext;
				if (pEvent && pEvent->cId > 0 && pEvent->cId == m_curState.cid)
				{
					g_GetTimerAxis()->KillTimer(0, this);
					CollectNotify notify;
					notify.set_collect_type(m_curState.byType);
					notify.set_state(ECollectState_Break);
					notify.set_collect_cid(m_curState.cid);
					m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_NOTIFY_COLLECT, &notify);
					m_curState.Clear();
					BroadcastCollectAction();
					NotifyError(RET_DEPUTY_COLLECT_BY_OTHER);
					UnSubEvent();
				}
			}
		}
	}
	default:
		break;
	}
}

void CollectPart::OnTimer(uint32_t nTimerID)
{
	switch (nTimerID)
	{
	case 0:
	{
		UnSubEvent();

		ERetCode retCode = RET_FAIL;
		CollectFinish(retCode);
		if (retCode != RET_FAIL && retCode != RET_SUCCESS)
		{
			NotifyError(retCode);
		}
		ECollectState state = (retCode == RET_PACKAGE_SPACE_NOT_ENOUGH) ? ECollectState_Break : ECollectState_End/*ECollectState_Auto*/;
		NotifyState(state);
		m_curState.Clear();
		BroadcastCollectAction();
	}
	break;
	default:
		break;
	}
}

void CollectPart::Collect(const char *data, uint32_t len)
{
	CollectOperateReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] CollectPart::Collect....CollectOperateReq parse failed....");
		return;
	}

	uint32_t cfgId = 0;
	if (!CheckPeel(req.collect_cid(), cfgId))
	{
		return;
	}

	const ThingCollectCfgInfo *pCollectCfg = nullptr;
	const MonsterMonsterCfgInfo *pMonsterCfg = g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(cfgId);
	if (nullptr == pMonsterCfg)
	{
		pCollectCfg = g_GetDeputyCfgMgr()->GetMapThingCollectCfgInfo(cfgId);
	}
	else
	{
		pCollectCfg = g_GetDeputyCfgMgr()->GetMapThingCollectCfgInfo(pMonsterCfg->skinLink);
	}

	if (!CheckRes(cfgId, pCollectCfg))
	{
		return;
	}

	if (!CheckCond(pCollectCfg))
	{
		return;
	}

	CollectBegin(pCollectCfg, req);
}

void CollectPart::Qte(const char *data, uint32_t len)
{
	CollectQteReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] CollectPart::Qte....CollectQteReq parse failed....");
		return;
	}

	CollectQteRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	Scene *pScene = g_GetSceneMgr()->GetScene(m_pMaster->GetSceneId());
	if (nullptr == pScene)
	{
		LogErrFmtPrint("[logic] CollectPart::Qte....nullptr == pScene...sceneId:%u ", m_pMaster->GetSceneId());
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_QTE, &rsp);
		return;
	}

	Creature *pCreature = pScene->GetCreature(req.collect_cid());
	if (nullptr == pCreature)
	{
		LogErrFmtPrint("[logic] CollectPart::Qte....nullptr == pCreature...cid:%lu ", req.collect_cid());
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_QTE, &rsp);
		return;
	}

	if (ECollectState_Begin != m_curState.byState)
	{
		LogErrFmtPrint("[logic] CollectPart::CheckPeel....m_curState.byState = %d ", m_curState.byState);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_QTE, &rsp);
		return;
	}

	m_curState.qte = req.result();
	m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_QTE, &rsp);
}

void CollectPart::CollectSpecial(const char *data, uint32_t len)
{
	CollectSpecialReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] CollectPart::CollectSpecial....CollectSpecialReq parse failed....");
		return;
	}

	CollectSpecialRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("DeputyPart::CollectSpecial...nullptr == pPlayer");
		return;
	}

	Part *pPackage = m_pMaster->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		LogErrFmtPrint("DeputyPart::CollectSpecial...nullptr == pPackage");
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_SPECIAL, &rsp);
		return;
	}

	uint32_t cfgId = req.configid();
	const ThingCollectCfgInfo *pCollectCfg = nullptr;
	const MonsterMonsterCfgInfo *pMonsterCfg = g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(cfgId);
	if (nullptr == pMonsterCfg)
	{
		pCollectCfg = g_GetDeputyCfgMgr()->GetMapThingCollectCfgInfo(cfgId);
		if (nullptr == pCollectCfg)
		{
			LogErrFmtPrint("[logic] CollectPart::CollectSpecial....nullptr == pCollectCfg....cfgId):%u ", cfgId);
			rsp.set_retcode(RET_CONFIG_ERROR);
			m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_SPECIAL, &rsp);
			return;
		}
	}
	else
	{
		pCollectCfg = g_GetDeputyCfgMgr()->GetMapThingCollectCfgInfo(pMonsterCfg->skinLink);
		if (nullptr == pCollectCfg)
		{
			LogErrFmtPrint("[logic] CollectPart::CollectSpecial....nullptr == pCollectCfg....pMonsterCfg->skinLink):%u ", pMonsterCfg->skinLink);
			rsp.set_retcode(RET_CONFIG_ERROR);
			m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_SPECIAL, &rsp);
			return;
		}
	}

	ERetCode ret;
	ret = RET_SUCCESS;
	LIST_ITEM lstItem;
	VEC_ITEM_PROTO_EX vecProto;
	if (pCollectCfg->masterType == ECollectModuleType_Deputy)
	{
		if (pCollectCfg->getItemId > 0)										//采集资源
		{
			SItem item;
			item.nItemID = pCollectCfg->getItemId;
			item.nNum = 1;
			item.byBind = (int8_t)EBindState::EBindState_no;
			lstItem.push_back(item);
		}

		for (VecThingCollectAccompanimentsCfg::const_iterator iter = pCollectCfg->vecThingCollectAccompanimentsCfg.begin(); iter != pCollectCfg->vecThingCollectAccompanimentsCfg.end(); ++iter)
		{
			const ThingCollectAccompanimentsCfgInfo &cfgInfo = *iter;
			if (cfgInfo.Id <= 0)
				continue;

			if ((int32_t)Random(10000) <= cfgInfo.Rate)
			{
				SItem item;
				item.nItemID = cfgInfo.Id;
				item.nNum = 1;
				item.byBind = (int8_t)EBindState::EBindState_no;
				lstItem.push_back(item);
			}
		}

		if (!pPackage->CanAddItem(lstItem))
		{
			ret = RET_PACKAGE_SPACE_NOT_ENOUGH;
		}
	}
	else
	{
		int32_t gold, bindnum, diamnum;
		BoxCondCfg boncfg;
		g_GetDropMgr()->GetBoxCond(pPlayer, boncfg);
		g_GetItemMgr()->CreateBoxDropItem(pCollectCfg->drop, vecProto, gold, bindnum, diamnum, boncfg);
		if (!pPackage->CanAddItem(vecProto))
		{
			ret = RET_PACKAGE_SPACE_NOT_ENOUGH;
		}
	}
	
	rsp.set_retcode(ret);
	m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_SPECIAL, &rsp);

	if (ret == RET_SUCCESS)
	{
		SItemSourceParam sourceParam;
		sourceParam.source = S_DEPUTY;
		if (pCollectCfg->masterType == ECollectModuleType_Deputy)
		{
			pPackage->AddItem(lstItem, sourceParam);
		}
		else
		{
			pPackage->AddItem(vecProto, sourceParam);
		}
	}
}

void CollectPart::AddCollectSpeed(int32_t rate)
{
	mCollectSpeed += rate;
}
void CollectPart::DecCollectSpeed(int32_t rate)
{
	mCollectSpeed = mCollectSpeed >= rate ? mCollectSpeed - rate : mCollectSpeed;
}

bool CollectPart::CheckPeel(CharIDType cid, uint32_t &cfgId)
{
	bool result = true;
	ERetCode retcode = RET_SUCCESS;
	
	Scene *pScene = g_GetSceneMgr()->GetScene(m_pMaster->GetSceneId());
	if (nullptr == pScene)
	{
		LogErrFmtPrint("[logic] CollectPart::CheckPeel....nullptr == pScene...sceneId:%u ", m_pMaster->GetSceneId());
		retcode = RET_FAIL;
		result = false;
	}

	Creature *pCreature = result ? pScene->GetCreature(cid) : nullptr;
	if (nullptr == pCreature)
	{
		LogErrFmtPrint("[logic] CollectPart::CheckPeel....nullptr == pCreature...cid:%lu ", cid);
		retcode = RET_DEPUTY_RES_NOT_EXIST;
		result = false;
	}

	if (result && pCreature && CREATURE_MONSTER == pCreature->CreatureKind())		//剥皮
	{
		Monster* pMonster = dynamic_cast<Monster*>(pCreature);
		if (nullptr == pMonster)
		{
			LogErrFmtPrint("[logic] CollectPart::CheckPeel....nullptr == pMonster...cid:%lu ", cid);
			retcode = RET_FAIL;
			result = false;
		}
		else if (m_pMaster->GetCid() != pMonster->GetKillerID())
		{
			retcode = RET_DEPUTY_PEEL_NO_RIGHT;
			result = false;
		}
		else if (!pMonster->IsDead())
		{
			retcode = RET_DEPUTY_MONSTER_NOT_DEAD;
			result = false;
		}
		else if (pMonster->GetBoPiNum() > 0)
		{
			retcode = RET_DEPUTY_COLLECT_BY_OTHER;
			result = false;
		}
	}
	if (false == result)
	{
		CollectOperateRsp rsp;
		rsp.set_retcode(retcode);
		m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_COLLECT_OPERATE, &rsp);
	}
	else
	{
		cfgId = pCreature->GetConfigId();
	}
	return result;
}

void CollectPart::BroadcastCollectAction()
{
	CollectData cData;
	cData.set_cid(m_pMaster->GetCid());
	cData.set_collect_type(m_curState.byType);
	m_pMaster->BroadCastData(EMOUDLE_ID_COLLECT, LOGIC_TO_CLIENT_COLLECT_ACTION_BROADCAST, (ProtoBufBase*)&cData, true);
}

bool CollectPart::CheckRes(uint32_t cfgId, const ThingCollectCfgInfo *pCollectCfg)
{
	bool result = true;
	ERetCode retcode = RET_SUCCESS;

	if (nullptr == pCollectCfg)
	{
		LogErrFmtPrint("[logic] CollectPart::CheckRes....nullptr == pCollectCfg....cfgId):%u ", cfgId);
		retcode = RET_CONFIG_ERROR;
		result = false;
	}
	else if (pCollectCfg->type <= CollectData_Type_None || pCollectCfg->type >= CollectData_Type_Limit)
	{
		LogErrFmtPrint("[logic] CollectPart::CheckRes...pCollectCfg->type <= CollectData_Type_None || pCollectCfg->type >= CollectData_Type_Limit  type:%d ", pCollectCfg->type);
		retcode = RET_DEPUTY_CONFIG_TYPE_ERROR;
		result = false;
	}
	
	if (false == result)
	{
		CollectOperateRsp rsp;
		rsp.set_retcode(retcode);
		m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_COLLECT_OPERATE, &rsp);
	}
	return result;
}

bool CollectPart::CheckCond(const ThingCollectCfgInfo *pCollectCfg)
{
	ERetCode retcode = RET_SUCCESS;

	if (pCollectCfg->masterType == ECollectModuleType_Deputy)
	{
		const ConstantConstantCfgInfo* pConstCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_OpenCollectLel);
		if (nullptr == pConstCfg)
		{
			LogErrFmtPrint("[logic] CollectPart::CheckCond....pConstCfg=nullptr ...=failed....");
			retcode = RET_CONFIG_ERROR;
		}
		else if (m_pMaster->GetAttr(C_LEVEL) < pConstCfg->constantdata)
		{
			retcode = RET_LEVEL_LACK;
		}
	}
	else if (pCollectCfg->masterType == ECollectModuleType_Task)
	{
		MissionPart *pMission = (MissionPart*)m_pMaster->GetPart(PART_MISSION);
		if (pMission)
		{
			m_curState.dropId = pCollectCfg->drop;
		}
		else
		{
			LogErrFmtPrint("[logic] CollectPart::CheckCond....pMission=nullptr ...=failed....");
			retcode = RET_FAIL;
		}
	}
	if (retcode == RET_SUCCESS)
	{
		return true;
	}
	CollectOperateRsp rsp;
	rsp.set_retcode(retcode);
	m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_COLLECT_OPERATE, &rsp);

	return false;
}

void CollectPart::CollectBegin(const ThingCollectCfgInfo *pCfg, CollectOperateReq &req)
{
	CollectOperateRsp rsp;
	rsp.set_retcode(RET_FAIL);
	rsp.set_collect_type(pCfg->type);

	/*const ConstantConstantCfgInfo *pConstCollSecCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputyCollSec);
	if (nullptr == pConstCollSecCfg)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		LogErrFmtPrint("[logic] CollectPart::CollectBegin.....nullptr == pConstCollSecCfg, id:%d ", EArg_DeputyCollSec);
	}
	else */if (ECollectState_Begin == m_curState.byState)
	{
		NotifyError(RET_DEPUTY_COLLECT_BREAK);
		g_GetTimerAxis()->KillTimer(0, this);
		NotifyState(ECollectState_Break);
		m_curState.Clear();
		BroadcastCollectAction();
	}
	else
	{
		MovePart *pMove = (MovePart*)m_pMaster->GetPart(PART_MOVE);
		if (nullptr == pMove)
		{
			LogErrFmtPrint("[logic] CollectPart::CollectBegin  nullptr == pMove... ");
		}
		else if (pMove->IsMoving())									//正在移动
		{
			rsp.set_retcode(RET_DEPUTY_COLLECT_IN_MOVE);
		}
		else if ((int32_t)m_pMaster->GetAttr(C_ENERGY) < pCfg->needEnergy)	//活力值不够
		{
			rsp.set_retcode(RET_DEPUTY_LACK_ENERGY);
		}
		else														//可以采集
		{
			g_GetTimerAxis()->KillTimer(0, this);
			uint64_t collectTime = pCfg->readTime * 100 / (100 + mCollectSpeed);
			if (!g_GetTimerAxis()->SetTimer(0, collectTime + 500, this, 1))	//服务器延迟一秒完成采集 确保前端的读条完成之后
			{
				LogErrFmtPrint("[logic] CollectPart::CollectBegin....SetTimer failed serious error.....");
			}
			else
			{
				rsp.set_retcode(RET_SUCCESS);
				m_curState.cid = req.collect_cid();
				m_curState.byState = ECollectState_Begin;
				m_curState.byType = (CollectData_Type)pCfg->type;
				m_curState.collectTime = collectTime;
				NotifyState(m_curState.byState);
				BroadcastCollectAction();
			}
		}
	}

	m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_COLLECT_OPERATE, &rsp);

	SubEvent();
}

void CollectPart::CollectFinish(ERetCode &retcode)
{
	Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr == pPlayer)
	{
		return;
	}

	Scene *pScene = g_GetSceneMgr()->GetScene(m_pMaster->GetSceneId());
	if (nullptr == pScene)
	{
		LogErrFmtPrint("[logic] CollectPart::CollectFinish....nullptr == pScene....sceneId):%u ", m_pMaster->GetSceneId());
		return;
	}

	Creature *pCreature = pScene->GetCreature(m_curState.cid);
	if (nullptr == pCreature)
	{
		retcode = RET_DEPUTY_COLLECT_BY_OTHER;
		return;
	}

	Part *pPackage = m_pMaster->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		return;
	}

	DeputyPart *pDeputy = (DeputyPart*)m_pMaster->GetPart(PART_DEPUTY);
	if (nullptr == pDeputy)
	{
		return;
	}

	uint32_t cfgId = pCreature->GetConfigId();
	const ThingCollectCfgInfo *pCollectCfg = nullptr;
	const MonsterMonsterCfgInfo *pMonsterCfg = g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(cfgId);
	if (nullptr == pMonsterCfg)
	{
		pCollectCfg = g_GetDeputyCfgMgr()->GetMapThingCollectCfgInfo(cfgId);
		if (nullptr == pCollectCfg)
		{
			LogErrFmtPrint("[logic] CollectPart::CollectFinish....nullptr == pCollectCfg....cfgId):%u ", cfgId);
			return;
		}
	}
	else
	{
		pCollectCfg = g_GetDeputyCfgMgr()->GetMapThingCollectCfgInfo(pMonsterCfg->skinLink);
		if (nullptr == pCollectCfg)
		{
			LogErrFmtPrint("[logic] CollectPart::CollectFinish....nullptr == pCollectCfg....pMonsterCfg->skinLink):%u ", pMonsterCfg->skinLink);
			return;
		}
	}

	if (pCollectCfg->type <= CollectData_Type_None || pCollectCfg->type >= CollectData_Type_Limit)
	{
		LogErrFmtPrint("[logic] CollectPart::CollectFinish...pCollectCfg->type <= ECollectDepuECollectType_NonetyType_None || pCollectCfg->type >= ECollectType_Limit  type:%d ", pCollectCfg->type);
		return;
	}
	if (pCollectCfg->type != m_curState.byType)
	{
		LogErrFmtPrint("[logic] CollectPart::CollectFinish...pCollectCfg->type != m_curState.byType  cfgtype:%d,curType:%d  ", pCollectCfg->type, m_curState.byType);
		return;
	}

	LIST_ITEM lstItem;
	VEC_ITEM_PROTO_EX vecProto;
	if (pCollectCfg->masterType == ECollectModuleType_Deputy)
	{
		retcode = pDeputy->CollectFinish(pCollectCfg, lstItem);
	}
	else if (pCollectCfg->masterType == ECollectModuleType_Task)
	{
		int32_t gold, bindnum, diamnum;
		BoxCondCfg boncfg;
		g_GetDropMgr()->GetBoxCond(pPlayer, boncfg);
		g_GetItemMgr()->CreateBoxDropItem(m_curState.dropId, vecProto, gold, bindnum, diamnum, boncfg);
		if (pPackage->CanAddItem(vecProto))
		{
			retcode = RET_SUCCESS;
		}
	}

	if (RET_SUCCESS == retcode || RET_DEPUTY_COLLECT_ERROR == retcode)
	{
		g_GetObjectMgr()->CollectScuess(pCreature);
	}

	if (RET_SUCCESS == retcode)
	{
		CollectSuccessEvent collectEvent;
		collectEvent.cid = pCreature->GetCid();
		collectEvent.sonType = pCollectCfg->type;
		g_GetEvent()->FireExecute(EVENT_COLLECT_SUCCESS, m_pMaster->GetCid(), CREATURE_DROP, &collectEvent, sizeof(CollectSuccessEvent));

		if (pCollectCfg->masterType == ECollectModuleType_Deputy)
		{
			pDeputy->CollectGain(pCollectCfg, lstItem);
		}
		else if (pCollectCfg->masterType == ECollectModuleType_Task)
		{
			SItemSourceParam sourceParam;
			sourceParam.source = S_DEPUTY;
			pPackage->AddItem(vecProto, sourceParam);
		}
	}
}

void CollectPart::NotifyState(int32_t state, bool begin)
{
	CollectNotify notify;
	notify.set_collect_type(m_curState.byType);
	notify.set_state(state);
	if (begin)
	{
		notify.set_collect_time(m_curState.collectTime);
	}
	m_pMaster->SendDataToClient(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_NOTIFY_COLLECT, &notify);
}

void CollectPart::NotifyError(int32_t errorCode)
{
	CollectNotifyError notify;
	notify.set_retcode(errorCode);
	m_pMaster->SendDataToClientEx(EMOUDLE_ID_COLLECT, SERVER_TO_CLIENT_COLLECT_NOTIFY_ERROR, &notify);
}

void CollectPart::SubEvent()
{
	g_GetEvent()->Subscribe(this, EVENT_START_MOVE, m_pMaster->GetCid(), CREATURE_PLAYER, "CollectPart::Init");
	g_GetEvent()->Subscribe(this, EVENT_LEAVE_SCENE, 0, CREATURE_DROP, "CollectPart::Init");
	g_GetEvent()->Subscribe(this, EVENT_LEAVE_SCENE, 0, CREATURE_MONSTER, "CollectPart::Init");
	g_GetEvent()->Subscribe(this, EVENT_UNDER_ATTACK, m_pMaster->GetCid(), 0, "CollectPart::Init");
	g_GetEvent()->Subscribe(this, EVENT_ATTACK_SOMEBODY, m_pMaster->GetCid(), 0/*CREATURE_PLAYER*/, "CollectPart::Init");
	g_GetEvent()->Subscribe(this, EVENT_COLLECT_SUCCESS, 0, CREATURE_DROP, "CollectPart::Init");
}

void CollectPart::UnSubEvent()
{
	g_GetEvent()->UnSubscribeAll(this);
}
